package com.deepgames.mud.action;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.deepgames.mud.action.data.ActionContext;
import com.deepgames.mud.action.data.Command;
import com.deepgames.mud.core.InternalCode;
import com.deepgames.mud.core.Message;
import com.deepgames.mud.gobject.GobjectExtractor;
import com.deepgames.mud.session.SessionManager;

/**
 * Processes game logic by interpreting user commands and executing actions
 * 	using a SessionManager and GobjectExtractor instances.
 * 
 * @author Zack Hoffmann
 * @version 0.1
 *
 */
public class ActionEngine {

	private SessionManager sessions;
	private ActionLibrary library;
	private ActionContext context;
	private Logger log;

	/**
	 * Constructor given specific SessionManager and GobjectExtractor 
	 * 	instances.
	 * 
	 * @param sessions		This game's SessionManager instance.
	 * @param gobjects		This game's GobjectExtractor instance.
	 */
	public ActionEngine(SessionManager sessions, GobjectExtractor gobjects) {
		this.log = Logger.getLogger(ActionEngine.class.getName());
		this.log.setLevel(Level.parse(System.getenv("deepmud.log.level")));
		this.sessions = sessions;
		this.library = new ActionLibrary();
		this.context = new ActionContext(sessions, gobjects, library);
	}
	
	public int run() {
		int status = InternalCode.SUCCESS;
		
		while (true) {
			
			Message msg;
			Command cmd;
			
			/*
			 * Get next message from queue.
			 */			
			msg = sessions.getNextMsgFromPlayers();
			
			/*
			 * Convert message to command.
			 */			
			cmd = interpretCommand(msg);
			
			/*
			 * Execute command.
			 */			
			status = cmd.execute(context);
			
			if (status != InternalCode.SUCCESS) {
				log.warning("Action execution status code: " + status);
				break;
			}
		}
		
		return status;
	}
	
	/**
	 * Translates a Message object in to a Command object for use with this
	 * 	ActionEngine.  This implementation will transform any commands from a
	 * 	Guest ID in to a "LOGIN" action.
	 * 
	 * @param msg			Message with unique player ID and plain-text
	 * 						command.
	 * @return				Command object qualified for this ActionEngine
	 * 						instance.
	 */
	private Command interpretCommand(Message msg) {
		Command cmd = null;
		
		String playerID = msg.getPlayerID();
		String msgText = msg.getMsg().trim();
		if (playerID.contains("GUEST")) {
			cmd = new Command(library.lookupAction("LOGIN"), "SYSTEM", 
					playerID + " " + msgText);
		}
		else {
			int delimiter = msgText.indexOf(" ");
			
			if (delimiter == -1) {
				cmd = new Command(library.lookupAction(msgText), playerID, 
						null);
			}
			else {
				cmd = new Command(
						library.lookupAction(msgText.substring(0, delimiter)), 
						playerID, msgText.substring(delimiter + 1));
			}
		}
		
		return cmd;
	}
	
}
